﻿using An_Im.Core;
using An_Im.Model;
using An_Im.Theme.Custom;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml;
using IO = System.IO;
using WF = System.Windows.Forms;

namespace An_Im.UI
{
    /// <summary>
    /// AnImRecorderControl.xaml 的交互逻辑
    /// </summary>
    public partial class AnImRecorderControl : UserControl
    {

        private IEnumerable<AnListBox> AnListBoxes
        {
            get
            {
                var border = VisualTreeHelper.GetChild(itemsControls_lv1, 0);
                var itemspresenter = VisualTreeHelper.GetChild(border, 0);
                var stackpanel = VisualTreeHelper.GetChild(itemspresenter, 0);

                var list = new List<AnListBox>();
                var childrenCount = VisualTreeHelper.GetChildrenCount(stackpanel);

                for (int i = 0; i < childrenCount; i++)
                {
                    var contentpresent = VisualTreeHelper.GetChild(stackpanel, i);
                    var grid = VisualTreeHelper.GetChild(contentpresent, 0);
                    var anlist = VisualTreeHelper.GetChild(grid, 1) as AnListBox;
                    if (anlist == null) continue;
                    list.Add(anlist);
                }
                return list;
            }
        }

        private IEnumerable<EffectInformation> SelectedEffects
        {
            get
            {
                var list = new List<EffectInformation>();

                foreach (var listBox in AnListBoxes)
                {
                    list.AddRange(listBox.SelectedItems.OfType<EffectInformation>());
                }

                return list;

            }
        }


        public AnImRecorderControl()
        {
            InitializeComponent();
            itemsControls_lv1.ItemsSource = CustomAnimationLib.TagDictionary.Values;
            PreviewDrop += AnImRecorderControl_PreviewDrop;
            this.MouseLeftButtonUp += AnImRecorderControl_MouseLeftButtonUp;

            scrollviewer.PreviewMouseWheel += scrollViewer_PreviewMouseWheel;

        }


        private void AnImRecorderControl_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var rst = VisualTreeHelper.HitTest(this, e.GetPosition(this));
            if (rst == null) return;
            var visualrst = rst.VisualHit as FrameworkElement;
            if (visualrst == null) UnselectAllEffects();
            else if (visualrst.DataContext is EffectInformation == false)
                UnselectAllEffects();
            else
            {
                if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl) || Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
                    return;
                //UnselectAllEffects();
                nameTextBox.DataContext = null;
                foreach (EffectInformation animData in SelectedEffects)
                {
                    nameTextBox.DataContext = animData;
                    //CoreManipulator.AddTargetAnimationOnSelectionShapeRange(animData);
                }
            }
        }


        // 不选择所有选择的效果。
        private void UnselectAllEffects()
        {
            foreach (AnListBox list in AnListBoxes)
            {
                list.UnselectAll();
            }
        }

        private void AnImRecorderControl_PreviewDrop(object sender, DragEventArgs e)
        {
            var datas = e.Data.GetData(DataFormats.FileDrop) as string[];
            var xmldoc = new XmlDocument();
            foreach (var path in datas)
            {
                var ext = IO.Path.GetExtension(path);
                if (IO.Path.GetExtension(ext) != ".anx") continue;
                var stream = new IO.FileStream(path, IO.FileMode.Open);
                var bytelist = new List<byte>();
                var tempbyte = int.MaxValue;
                while (true)
                {
                    tempbyte = stream.ReadByte();
                    if (tempbyte == -1) break;
                    bytelist.Add((byte)tempbyte);
                }
                var str = Encoding.Default.GetString(bytelist.ToArray());
                stream.Close();
                xmldoc.LoadXml(str);
                if (xmldoc.DocumentElement.Name == "动画效果")
                {
                    CustomAnimationLib.Add(CoreManipulator.LoadArtificialEffectInformation(xmldoc.DocumentElement));
                }
                else if (xmldoc.DocumentElement.Name == "组动画效果")
                {
                    CustomAnimationLib.Add(CoreManipulator.LoadGroupEffectInformation(xmldoc.DocumentElement));
                }
                else if (xmldoc.DocumentElement.Name == "原生动画效果")
                {
                    CustomAnimationLib.Add(CoreManipulator.LoadNativeEffectInformation(xmldoc.DocumentElement));
                }

            }
           

        }


        /// <summary>
        /// 另存为
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void saveAsButton_Click(object sender, RoutedEventArgs e)
        {
            foreach (EffectInformation animData in SelectedEffects)
            {
                using (var dialog = new WF.SaveFileDialog())
                {
                    dialog.SupportMultiDottedExtensions = false;
                    dialog.DefaultExt = "anx";
                    dialog.Filter = "ANY 插件动画信息格式|*.anx";
                    dialog.FileName = animData.Name + ".anx";
                    dialog.InitialDirectory = CoreManipulator.CustomAnimationExportPath;
                    if (dialog.ShowDialog() == WF.DialogResult.OK)
                    {
                        using (var stream = IO.File.OpenWrite(dialog.FileName))
                        {
                            animData.Name = IO.Path.GetFileNameWithoutExtension(dialog.FileName);
                            var xmlinfo = CoreManipulator.ExportEffect(animData);
                            var bytes = Encoding.Default.GetBytes(xmlinfo);
                            stream.Write(bytes, 0, bytes.Length);
                        }
                    }
                }
            }
        }

        private void addVBAItem_Click(object sender, RoutedEventArgs e)
        {
            foreach (EffectInformation animData in SelectedEffects)
            {
                if (animData is ArtificialEffectInformation)
                    VBAManipulator.Write(CoreManipulator.CreateArtificialVBACode(animData as ArtificialEffectInformation));
            }

        }

        private void recordButton_Click(object sender, RoutedEventArgs e)
        {
            var effs = CustomAnimationLib.GetEffectInfomations(CoreManipulator.GetEffectsFromShapeRange(), false);
            CustomAnimationLib.AddRange(effs);
        }

        private void deleteItem_Click(object sender, RoutedEventArgs e)
        {
            foreach (AnListBox anlist in itemsControls_lv1.Items)
            {
                var efflist = anlist.ItemsSource as List<EffectInformation>;
                var list = new List<EffectInformation>(anlist.SelectedItems.OfType<EffectInformation>());
                foreach (EffectInformation animData in list)
                {
                    efflist.Remove(animData);
                }
            }
            itemsControls_lv1.Items.Refresh();
        }

        private void saveButton_Click(object sender, RoutedEventArgs e)
        {
            CustomAnimationLib.Save();
        }

        private void animList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            nameTextBox.DataContext = null;
            foreach (EffectInformation animData in SelectedEffects)
            {
                nameTextBox.DataContext = animData;
                //CoreManipulator.AddTargetAnimationOnSelectionShapeRange(animData);
            }

        }

        private void addItem_Click(object sender, RoutedEventArgs e)
        {
            nameTextBox.DataContext = null;
            foreach (EffectInformation animData in SelectedEffects)
            {
                nameTextBox.DataContext = animData;
                CoreManipulator.AddTargetAnimationOnSelectionShapeRange(animData);
            }
        }

        private void groupItem_Click(object sender, RoutedEventArgs e)
        {
            if (SelectedEffects.Count() == 0) return;
            CustomAnimationLib.Add(CoreManipulator.RecordGroupEffect(SelectedEffects.OfType<EffectInformation>(), "组合" + new Random().Next(1000, 9999), null, null));
        }


        private void scrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
            eventArg.RoutedEvent = UIElement.MouseWheelEvent;
            eventArg.Source = e.Source;

            ScrollViewer scv = (ScrollViewer)sender;
            scv.RaiseEvent(eventArg);
            e.Handled = true;
        }

        private void DataGrid_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            // 直接跳转至上述scrollViewer的滚动事件
            scrollViewer_PreviewMouseWheel(scrollviewer, e);
        }

        // 添加单条动画
        private void addEffectButton_Click(object sender, RoutedEventArgs e)
        {
            var button = sender as FrameworkElement;
            var eff = button.DataContext as EffectInformation;
            if (eff != null)
            {
                CoreManipulator.AddTargetAnimationOnSelectionShapeRange(eff);
            }
        }
    }
}
